with sharing global class JointCallDownloadHCPHospitalWebService{

    global class WebToPDAMedical{
        webservice List<Hospital__c> NeedInsertHospital;
        webservice List<Hospital__c> NeedUpdateHospital;
        webservice List<HCP__c> NeedInsertHCP;
        webservice List<HCP__c> NeedUpdateHCP;
        webservice List<id> NeedDelHospital;
        webservice List<id> NeedDelHCP;
        webservice List<User> MsrList;
        webservice Boolean ResetPDA;
        webservice string debugNum; //debug
    }
    
    global class inputClass{
        webservice Boolean downloadAll;
    }
    static String HospitalIn = 'HospitalIn';
    static String HcpIn = 'HcpIn';

    static List<PDAMasterDataBackup__c> DeletePDAMasterData = new List<PDAMasterDataBackup__c>();
    static List<PDAMasterDataBackup__c> InsertPDAMasterData = new List<PDAMasterDataBackup__c>();
    
    
   @future(callout = true)
    public static void UpdatePDAMasterData()
    {
        List<PDAMasterDataBackup__c> InsertPDAMasterDatas = new List<PDAMasterDataBackup__c>();
        delete [Select CreatedDate,id From PDAMasterDataBackup__c where OwnerId  =: UserInfo.getUserId()];
   
        list<jointCall__c> jointcall=[select HospitalID__c,HCPID__c from jointcall__c where CallDate__c >:date.today().addmonths(-2)];
        list<id> hospitalIDList=new list<id>();
        list<id> HCPIDList=new list<id>();
        for(jointcall__c j:jointcall){
            hospitalIDList.add(j.HospitalID__c);
            HCPIDList.add(j.HCPID__c);
        }
        List<Hospital__c> UpdateHosLists=new list<hospital__c>();
        if(hospitalidlist.size()>0)
        UpdateHosLists = [Select class__c, HospitalCode__c, Nickname__c,effectivedate__c, Id, Name, type1__c, 
                             OwnerId,Isdeleted,Active__c,approvaltype__c from Hospital__c where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:hospitalIDList];
        List<HCP__c> UpdateHcpLists=new list<hcp__c>();
        if(hcpidlist.size()>0)
        UpdateHcpLists = [Select class1__c,class2__c,Active__c,effectivedate__c, class3__c,IsDeleted, Dept__c, approvaltype__c,
                            HCPCode__c, Hospital__c,Id,Name,Hospital__r.effectivedate__c,Hospital__r.OwnerId,Hospital__r.Active__c from HCP__c 
                            where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:HCPIDList limit 3000];  



                              
        for(Hospital__c hos :UpdateHosLists ){
            PDAMasterDataBackup__c pdaHos = new PDAMasterDataBackup__c(ID__c = hos.id, Type__c = 'Hospital_M');
            InsertPDAMasterDatas.add(pdaHos);
        }
        for(HCP__c hcp :UpdateHcpLists ){
            PDAMasterDataBackup__c pdaHcp = new PDAMasterDataBackup__c(ID__c = hcp.id, Type__c = 'HCP');
            InsertPDAMasterDatas.add(pdaHcp);
        }
        insert InsertPDAMasterDatas;   
    }


    public static void AddMsrList(WebToPDAMedical ReturnBack)
    {
        List<User> AddMsr = new List<User>();
            
        List<User> subList = [Select Alias,Id,Name,UserRoleId,Title__c From User Where Id =:UserInfo.getUserId() and IsActive=:true];
        if(subList.size() > 0){
            Boolean haveflag = false;
            User currentRole = subList.get(0);
            List<User> u = [Select Alias,Id,Name,UserRoleId,Title__c From User Where Title__c = 'Sales Rep' and FunctionDepartment__c ='Medical Sales' and IsActive=:true];
            if(u.size() > 0)
            {
                if(currentRole.UserRoleId != u.get(0).UserRoleId){           
                    List<UserRole> sur1 = [Select Id,Name From UserRole Where ParentRoleId =: currentRole.UserRoleId];
                    List<User> secondLine = new List<User>();                   
                    for(UserRole urole:sur1){
                        List<User> sub1 = [Select Alias,Id,Name,UserRoleId,Title__c  From User Where UserRoleId  =: urole.Id and IsActive=:true];                                                           
                        for(User user:sub1){
                            haveflag = true;
                            secondLine.add(user);
                            if(user.Title__c == 'Sales Rep')
                                AddMsr.add(user);
                        }
                    }
                    Boolean loopflag = true; 
                    Boolean firsttime = true;
                    List<User> NextUser = new List<User>();
                    List<User> ComUser = new List<User>();
                    
                    while(loopflag){
                        if(secondLine.size() > 0)
                        {                                                                 
                            List<UserRole> NextRole = [Select Id,Name From UserRole Where ParentRoleId =: secondLine.get(0).UserRoleId];
                            List<ID> NextRoleId = new List<ID>();
                            for(UserRole ur : NextRole ){
                                NextRoleId.add(ur.Id);
                            }
                            if(NextRole.size() <= 0){
                                break;
                            }                                                                            
                            NextUser = [Select Alias,Id,Name,UserRoleId,Title__c From User Where UserRoleId  in: NextRoleId and IsActive=:true];
                            for(User add : NextUser)
                            {
                                if(add.Title__c == 'Sales Rep')
                                    AddMsr.add(add);
                                secondLine = NextUser.clone();                                
                            }
                            if(NextUser.get(0).Title__c == 'Sales Rep')
                            {
                                break;
                            }                                               
                        }                                          
                    }
                }  
            }
        }  
        ReturnBack.MsrList = AddMsr;   
    }

// get all data
// ResetOrNot is true. 1. clear the PDA, 2. get all data
// ResetOrNot is false. get all data   
    public static WebToPDAMedical ReturnAllData(Boolean ResetOrNot)
    {

    
        List<Hospital__c> UpdateHosList = new List<Hospital__c>(); 
        List<HCP__c> UpdateHcpList = new List<HCP__c>();        
        List<id> DeleteHosList = new List<id>();
        List<id> DeleteHcpList = new List<id>();

        
        //init WebToPDAMedical data
        WebToPDAMedical ReturnBack = new WebToPDAMedical();
        ReturnBack.ResetPDA = ResetOrNot;

        list<jointCall__c> jointcall=[select HospitalID__c,HCPID__c from jointcall__c where CallDate__c >:date.today().addmonths(-2)];
        list<id> hospitalIDList=new list<id>();
        list<id> HCPIDList=new list<id>();
        for(jointcall__c j:jointcall){
            hospitalIDList.add(j.HospitalID__c);
            HCPIDList.add(j.HCPID__c);
        }
        if(hospitalidlist.size()>0)
        UpdateHosList = [Select class__c, HospitalCode__c, Nickname__c,effectivedate__c, Id, Name, type1__c, 
                             OwnerId,Isdeleted,Active__c,approvaltype__c from Hospital__c where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:hospitalIDList];
        if(hcpidlist.size()>0)
        UpdateHcpList = [Select class1__c,class2__c,Active__c,effectivedate__c, class3__c,IsDeleted, Dept__c, approvaltype__c,
                            HCPCode__c, Hospital__c,Id,Name,Hospital__r.effectivedate__c,Hospital__r.OwnerId,Hospital__r.Active__c from HCP__c 
                            where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:HCPIDList limit 3000];

                          
        DeletePDAMasterData  = [Select CreatedDate,id From PDAMasterDataBackup__c];
        for(Hospital__c hos :UpdateHosList){
            PDAMasterDataBackup__c pdaHos = new PDAMasterDataBackup__c(ID__c = hos.id, Type__c = 'Hospital_M');
            InsertPDAMasterData.add(pdaHos);
        }
        for(HCP__c hcp :UpdateHcpList ){
            PDAMasterDataBackup__c pdaHcp = new PDAMasterDataBackup__c(ID__c = hcp.id, Type__c = 'HCP');
            InsertPDAMasterData.add(pdaHcp);
        }
        UpdatePDAMasterData();
        
        ReturnBack.NeedInsertHospital = UpdateHosList;
        ReturnBack.NeedInsertHCP = UpdateHcpList;
        
        return ReturnBack;   
    }

    // get approval data
    public static List<Id> GetApprovalHistory(List<id> ids,String input,datetime updateDate)
    {
        List<id> returnIds = new List<id>();
        List<String> HosApprovalNames = new List<String>();
        HosApprovalNames.add('医院重命名');
        HosApprovalNames.add('改变医院级别');
        List<String> HcpApprovalNames = new List<String>();
        HcpApprovalNames.add('改变医护人员级别');
         
        if(input == HospitalIn)
        {
            if(ids.size() >0){
             List<HospitalChangeHistory__c> HospitalHistoryNeed = [Select id,Hospital__c From HospitalChangeHistory__c Where
                                                         Hospital__c in: ids
                                                         and CreatedDate >=: updateDate - 1
                                                         and Name in: HosApprovalNames];
             for(HospitalChangeHistory__c hos : HospitalHistoryNeed )
             {
                 returnIds.add(hos.Hospital__c);
             }                                            
            }         
        }
        if(input == HcpIn)
        {
            if(ids.size() >0){
             List<HCPChangeHistory__c > HCPHistoryNeed = [Select id,HCP__c From HCPChangeHistory__c Where
                                                         HCP__c in: ids
                                                         and CreatedDate >=: updateDate -1 
                                                         and Name in: HcpApprovalNames ];
             for(HCPChangeHistory__c hcp : HCPHistoryNeed)
             {
                 returnIds.add(hcp.HCP__c);
             }
            }          
        }
        return returnIds;
    }


// main function  
    webService static WebToPDAMedical getIncrementalMedical(inputClass FromPDA)
    {
        List<Hospital__c> InsertHosList = new List<Hospital__c>();
        List<Hospital__c> UpdateHosList = new List<Hospital__c>();
        List<id> DeleteHosList = new List<id>();
        List<HCP__c> InsertHcpList = new List<HCP__c>();
        List<HCP__c> UpdateHcpList = new List<HCP__c>();
        List<id> DeleteHcpList = new List<id>();

        
        //init WebToPDAMedical data
        WebToPDAMedical ReturnBack = new WebToPDAMedical();
        ReturnBack.ResetPDA = false;
        
        if(FromPDA.downloadAll)
        {
            ReturnBack = ReturnAllData(false);
            ReturnBack.debugNum = 'first time call in'; // debug
            AddMsrList(ReturnBack);
            return ReturnBack;
        }
        else
        {
            List<PDAMasterDataBackup__c> ExistPDAMasterData = [Select CreatedDate,id,Type__c,ID__c From PDAMasterDataBackup__c Where OwnerId  =: UserInfo.getUserId()];
            if(ExistPDAMasterData.size() <= 0)
            {
                ReturnBack = ReturnAllData(true); // web have no backupdata, but PDA have . PDA need reset data.
                ReturnBack.debugNum = 'no data in back up table'; // debug
                AddMsrList(ReturnBack);
                return ReturnBack;
            }  
            
            datetime updateTime = ExistPDAMasterData[0].CreatedDate; // get last time
            
            DeletePDAMasterData = ExistPDAMasterData;
            List<PDAMasterDataBackup__c> ExistHos = new List<PDAMasterDataBackup__c>();
            List<PDAMasterDataBackup__c> ExistHcp = new List<PDAMasterDataBackup__c>();
            List<id> ExistHosIds = new List<id>();
            List<id> ExistHcpIds = new List<id>();


            Map<id,PDAMasterDataBackup__c> mapExistHos = new Map<Id,PDAMasterDataBackup__c>();
            Map<id,PDAMasterDataBackup__c> mapClearExistHos = new Map<Id,PDAMasterDataBackup__c>();
            Map<id,PDAMasterDataBackup__c> mapExistHcp = new Map<Id,PDAMasterDataBackup__c>(); 
            Map<id,PDAMasterDataBackup__c> mapClearExistHcp = new Map<Id,PDAMasterDataBackup__c>();
                                    
            for(PDAMasterDataBackup__c p : ExistPDAMasterData )
            {
                if(p.Type__c == 'Hospital_M')
                {
                    ExistHos.add(p);
                    ExistHosIds.add(p.ID__c);
                    mapExistHos.put(p.ID__c,p);
                    mapClearExistHos.put(p.ID__c,p);
                }
                else if(p.Type__c == 'HCP')
                {
                    ExistHcp.add(p);
                    ExistHcpIds.add(p.ID__c);
                    mapExistHcp.put(p.ID__c,p);
                    mapClearExistHcp.put(p.ID__c,p);
                } 
            }
            
            list<jointCall__c> jointcall=[select HospitalID__c,HCPID__c from jointcall__c where CallDate__c >:date.today().addmonths(-2)];
            list<id> hospitalIDList=new list<id>();
            list<id> HCPIDList=new list<id>();
            for(jointcall__c j:jointcall){
                hospitalIDList.add(j.HospitalID__c);
                HCPIDList.add(j.HCPID__c);
            }
// Hospital process

            List<Hospital__c> HaveSeenHos=new list<hospital__c>();
            if(hospitalidlist.size()>0)
            HaveSeenHos = [Select class__c, HospitalCode__c, Nickname__c,effectivedate__c, Id, Name, type1__c, 
                             OwnerId,Isdeleted,Active__c,approvaltype__c from Hospital__c where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:hospitalIDList];
            
            Map<id,Hospital__c> mapHaveSeenHos = new Map<Id,Hospital__c>(HaveSeenHos); 

            
// HCP process

            List<HCP__c> HaveSeenHcp=new list<HCP__c>();
            if(hcpidlist.size()>0)
            HaveSeenHcp = [Select class1__c,class2__c,Active__c,effectivedate__c, class3__c,IsDeleted, Dept__c,approvaltype__c, 
                            HCPCode__c, Hospital__c,Id,Name,Hospital__r.effectivedate__c,Hospital__r.OwnerId,Hospital__r.Active__c from HCP__c 
                            where (Active__c = true or approvalstatus__c = '审批通过但未生效') and id in:HCPIDList limit 2000];           
            Map<id,HCP__c> mapHaveSeenHcp = new Map<Id,HCP__c>(HaveSeenHcp);

            
            // add delete hcp
            for(PDAMasterDataBackup__c p : ExistHcp){              
                if(!mapHaveSeenHcp.containsKey(p.ID__c)){
                    DeleteHcpList.add(p.ID__c);
                    mapClearExistHcp.remove(p.id);
                }                     
            }
            // add insert hcp
            for(HCP__c h : HaveSeenHcp){
                if(!mapExistHcp.containsKey(h.id)){
                    InsertHcpList.add(h);
                    mapClearExistHcp.remove(h.id);  
                }
            }
            // add update hcp

            
// Hospital process            

            // add delete hospital
            for(PDAMasterDataBackup__c p :ExistHos){              
                if(!mapHaveSeenHos.containsKey(p.ID__c)){
                    DeleteHosList.add(p.ID__c);
                    mapClearExistHos.remove(p.id);    
                }                     
            }
            
            // add insert hospital
            for(Hospital__c h : HaveSeenHos){
                if(!mapExistHos.containsKey(h.id)){
                    ReturnBack.debugNum = h.id; // debug
                    InsertHosList.add(h);
                }
            }
            
            // add update hospital       
            List<id> clearExitHos = new List<id>();
            List<id> clearExitHcp = new List<id>();
            
            for(PDAMasterDataBackup__c p : mapClearExistHos.values()){
                clearExitHos.add(p.ID__c);
            }
            for(PDAMasterDataBackup__c p : mapClearExistHcp.values()){
                clearExitHcp.add(p.ID__c);
            }
                    

            List<Id> getFromApprovalHos = GetApprovalHistory(clearExitHos, HospitalIn, updateTime);
            // add update from hospital approval
            if(getFromApprovalHos.size()>0 && hospitalidlist.size()>0){
                UpdateHosList = [Select class__c, HospitalCode__c, Nickname__c,effectivedate__c, Id, Name, type1__c, 
                                 OwnerId, Isdeleted,Active__c,approvaltype__c From Hospital__c 
                                 Where id in: getFromApprovalHos and id in:hospitalidlist];
            }                 
                             
            // add update from hcp approval
            List<Id> getFromApprovalHcp = GetApprovalHistory(clearExitHcp, HcpIn, updateTime);
            if(getFromApprovalHos.size()>0 && hcpidlist.size()>0){
                UpdateHcpList = [Select class1__c,class2__c,Active__c,effectivedate__c, class3__c,IsDeleted, Dept__c, 
                                 HCPCode__c, Hospital__c,Id,Name,Hospital__r.effectivedate__c,Hospital__r.OwnerId,Hospital__r.Active__c from HCP__c 
                                 Where id in: getFromApprovalHcp and id in:hcpidlist];
            }                 

            for(Hospital__c hos : InsertHosList)
            {
                PDAMasterDataBackup__c pdaHos = new PDAMasterDataBackup__c(ID__c = hos.id, Type__c = 'Hospital_M');
                InsertPDAMasterData.add(pdaHos);
            }
            for(Hospital__c hos : UpdateHosList)
            {
                PDAMasterDataBackup__c pdaHos = new PDAMasterDataBackup__c(ID__c = hos.id, Type__c = 'Hospital_M');
                InsertPDAMasterData.add(pdaHos);
            }            
            for(HCP__c hcp :InsertHcpList){
                PDAMasterDataBackup__c pdaHcp = new PDAMasterDataBackup__c(ID__c = hcp.id, Type__c = 'HCP');
                InsertPDAMasterData.add(pdaHcp);
            }
            for(HCP__c hcp :UpdateHcpList){
                PDAMasterDataBackup__c pdaHcp = new PDAMasterDataBackup__c(ID__c = hcp.id, Type__c = 'HCP');
                InsertPDAMasterData.add(pdaHcp);
                ReturnBack.debugNum = 'add HCP id';
            }
            if(InsertPDAMasterData.size() > 0){
                UpdatePDAMasterData();
            }        

            ReturnBack.NeedInsertHospital = InsertHosList;
            ReturnBack.NeedUpdateHospital = UpdateHosList;
            ReturnBack.NeedDelHospital = DeleteHosList;
            ReturnBack.NeedInsertHCP = InsertHcpList;
            ReturnBack.NeedUpdateHCP = UpdateHcpList;
            ReturnBack.NeedDelHCP = DeleteHcpList;
            //ReturnBack.debugNum = 'run last'; // debug
            AddMsrList(ReturnBack);
            return ReturnBack;                       
                    
        }
    }     

}